package nl.haemers.ui.behaviours 
{
	import flash.display.InteractiveObject;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.display.DisplayObjectContainer;
	import nl.haemers.behaviours.BaseBehaviour;
	/**
	 * @author Jonathan Haemers
	 */
	public class Draggable extends BaseBehaviour implements IDraggable
	{
		public static const DRAGGING			:String = "dragging";
		/**
		 * DragEvent
		 */
		//[Event(DRAGGING, false, false)];
		 
		
		protected var hasDragEvent		:Boolean;
		protected var _snapToPixel		:Boolean;
		protected var _easing			:Boolean;
		protected var _bounds			:Rectangle;
		
		protected var newX				:Number;
		protected var newY				:Number;
		protected var newPoint			:Point;
		
		public function Draggable(target:InteractiveObject, snapToPixel:Boolean=true, bounds:Rectangle=null, easing:Boolean=false) 
		{
			_target = target;
			_snapToPixel = snapToPixel;
			_bounds = bounds;
			_easing = easing;
			
			if (_target.stage) init(); else _target.addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		/** Public methods **/
		
		/** Getters & Setters **/
		public function set bounds( value:Rectangle ) : void 
		{
			_bounds = value;
		}
		
		public function set snapToPixel( value:Boolean ) : void 
		{
			_snapToPixel = value;
		}
		
		public function set easing( value:Boolean ) : void
		{
			_easing = value;
		}
		
		/** Protected methods **/
		protected function init(e:Event = null) : void
		{
			configListeners();
			//hasDragEvent = _target.hasEventListener(DragEvent.DRAGGING);
		}
		
		protected function configListeners() : void
		{
			_target.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			_target.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
		}
		
		protected function mouseDownHandler(e:MouseEvent) : void
		{
			_target.stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
		}
		
		protected function enterFrameHandler(e:Event) : void
		{
			newX = (_snapToPixel) ? int(_target.stage.mouseX) : _target.stage.mouseX;
			newY = (_snapToPixel) ? int(_target.stage.mouseY) : _target.stage.mouseY;
			
			newPoint = checkPosition(newX, newY, _bounds);
			
			moveTarget(newPoint);
			/*
			if (hasDragEvent)
			{
				dispatchEvent(new Event(DRAGGING));
			}
			*/
		}
		
		protected function mouseUpHandler(e:MouseEvent) : void
		{
			_target.stage.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
		}
		
		protected function moveTarget(position:Point) : void
		{
			_target.x = position.x;
			_target.y = position.y;
		}
		
		protected function checkPosition(x:Number, y:Number, bounds:Rectangle=null) : Point
		{
			var pt:Point = new Point(x, y);
			if (bounds != null)
			{
				if (x < bounds.left || x > bounds.right)
				{
					pt.x = (x < bounds.left) ? bounds.left : bounds.right;
				}
				if (y < bounds.bottom || y > bounds.top)
				{
					pt.y = (y < bounds.bottom) ? bounds.bottom : bounds.top;
				}
			}
			return pt;
		}
	}

}